package com.zh.mycommon.util;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 常用的通用方法
 * 主要是一些通用的方法，不方便归类的
 *
 * @author Zhou
 * @date 21:28 2024/12/20
 */
public final class MyCommonUtil {

    // 从尾部开始比较两个字符串是否相等
    public static boolean equalsFromEnd(String s1, String s2) {
        if (s1 == null || s2 == null) {
            return false;
        }

        // 长度不同直接返回false（与String.equals()逻辑一致）
        int length = s1.length();
        if (length != s2.length()) {
            return false;
        }
        if (s1.charAt(0) != s2.charAt(0)) {
            return false;
        }

        // 从尾部开始逐字符比较
        for (int i = length - 1; i >= 1; i--) { //因为charAt(0)已经比较了，所以从1开始
            if (s1.charAt(i) != s2.charAt(i)) {
                return false;
            }
        }
        return true;
    }

    public static String base64Encode(String str) {
        if (str == null || str.isEmpty()) return "";
        return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
    }

    public static String base64Decode(String str) {
        if (str == null || str.isEmpty()) return "";
        return new String(Base64.getDecoder().decode(str), StandardCharsets.UTF_8);
    }

    public static String sha256Hex(String paramStr) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(paramStr.getBytes(StandardCharsets.UTF_8));
            // 将字节数组转换成 十六进制
            var hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 下划线转驼峰
     * 例如：user_name -> userName
     */
    public static String camelCase(String s) {
        if (s == null) return null;
        if (s.isBlank()) return s;
        if (s.indexOf('_') == -1) return s;

        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == '_') {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰转下划线
     * 例如：userName -> user_name
     */
    public static String underlineCase(String s) {
        if (s == null) return null;
        if (s.isBlank()) return s;

        int len = s.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (Character.isUpperCase(c) && i > 0) {
                sb.append("_");
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 读取ByteBuffer中的数据为string
     *
     * @param buffer 堆内存或直接内存的buffer
     * @return string
     */
    public static String readAsString(ByteBuffer buffer) {
        int originalPosition = buffer.position(); // 保存当前位置
        try {
            if (buffer.hasArray()) {
                // 处理基于堆数组的缓冲区
                return new String(
                        buffer.array(),
                        buffer.arrayOffset() + buffer.position(),
                        buffer.remaining(),
                        StandardCharsets.UTF_8
                );
            } else {
                // 处理其他类型的缓冲区
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);
                return new String(bytes, StandardCharsets.UTF_8);
            }
        } finally {
            buffer.position(originalPosition); // 恢复原始位置
        }
    }

    public static <O> Set<O> collectUnion(Collection<? extends O> A, Collection<? extends O> B) {
        assert A != null && B != null;

        Set<O> union = new HashSet<>(A);
        union.addAll(B);
        return union;
    }

    public static <O> Set<O> collectIntersection(Collection<? extends O> A, Collection<? extends O> B) {
        assert A != null && B != null;

        Set<O> intersection = new HashSet<>(A);
        intersection.retainAll(B);
        return intersection;
    }

    public static <O> Set<O> collectSubtract(Collection<? extends O> A, Collection<? extends O> B) {
        assert A != null && B != null;

        Set<O> difference = new HashSet<>(A);
        difference.removeAll(B);
        return difference;
    }

}
